
//shacharh
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/* Copyright ?1999,2000,2001 Intel Corp.  */
/*++

Module Name:  tchpdd.c

Abstract:
 Intel XSC1 StrongARM  platform touch driver routines.

Notes:
 Created: July 22, 1997
 Modified January 17, 2002

--*/
//------------------------------------------------------------------------------
// Include Files
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <tchddsi.h>
#include <ceddk.h>
#include <bsp.h>
#include "touch.h"

#include "monahans.h"
#include "xllp_defs.h"
#include "xllp_mfp.h"
#include "xllp_ost.h"
#include "xllp_gpio.h"

#include "xllp_tsi_micco_B0.h"
#include "micco.h"
//#include "xllp_pm_micco_B0.h" //shachar 
#include "xllp_intc.h"
#include "bsp_cfg.h"

#define SHACHARH_DEBUG	(0)

//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------

extern "C" HANDLE  hTouchPanelEvent; //ran ? 

//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------

static volatile P_XLLP_OST_T  g_pOSTRegs=NULL;
static UINT16 g_PreX=0;
static UINT16 g_PreY=0;


HANDLE	g_hMiccoDrv=NULL; //TSI micco handle
HANDLE	g_PenDownEvent = NULL; //TSI ISR Event handle
HANDLE	g_TSI_X_Y_ReadyEvent = NULL; //TSI ISR Event handle



HANDLE	g_hTouchIST = NULL;    // touch screen IST
DWORD	TouchISTThread(void* pParam);
HANDLE  g_hTouchIST_TerminateEvent= NULL;
//HANDLE	hevInterrupt=NULL;


#define TSP_MINX						80
#define TSP_MINY						80

#define TSP_MAXX						940
#define TSP_MAXY						940


void TSP_TransXY(INT *px, INT *py);



extern "C" BOOL TouchDriverCalibrationPointGet(TPDC_CALIBRATION_POINT *pTCP);

extern HANDLE  hTouchPanelEvent;               //@globalvar HANDLE | hTouchPanelEvent | Holds the event handle for
TOUCH_STATUS_T TsiRead_X_Y(int *X, int *Y);
TOUCH_STATUS_T ModifyMiccoReg(BYTE reg_address,BYTE set_mask,BYTE clear_mask,LPBYTE prevValue);
PEN_STATUS GetPenStatus();

DWORD gIntrTouch        = SYSINTR_TOUCH;
DWORD gIntrTouchChanged = SYSINTR_NOP;

//shacharh to save prev val of micco tsi regs 
BYTE	PrevAdcManControl_Val =0;
//BYTE	PrevAdcAutoControl_2_Val =0;


PEN_STATUS penStatus=PEN_STATUS_UP;



//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------

static BOOL SetMiccoTSIMode(MICOO_TSI_MODE mode)
{
    TOUCH_STATUS_T ret;
    if ( mode==TSI_PEN_DETECT)
    {
        //RETAILMSG(1,(TEXT("[TOUCH] Enter Pen Detect mode\r\n")));
        ret = ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2,PEN_DETECT_ENABLE_SET,AUTO_TSI_MASK_CLR,NULL);
    }
    else // TSI_AUTO
    { 
        //RETAILMSG(1,(TEXT("[TOUCH] Enter Auto mode\r\n")));
        ret = ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2,AUTO_TSI_ENABLE_SET,PEN_DETECT_MASK_CLR,NULL);
    }
    return ret==TOUCH_STATUS_SUCCESS;
}


static BOOL EnableTSI_LDO(void)
{
   
    TOUCH_STATUS_T ret;
    //Start:Enable LDO_ADC_ENABLE & tune MUX to TSI @  XLLP_MICCO_ADC_MAN_CONTROL
    ret = ModifyMiccoReg(XLLP_MICCO_ADC_MAN_CONTROL,  LDO_ADC_ENABLE_SET,MUX_MASK_CLR,&PrevAdcManControl_Val);
    if ( ret!= TOUCH_STATUS_SUCCESS)
    {
        RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] SetMiccoTSI ModifyMiccoReg failed\r\n")));
    }
    return(ret== TOUCH_STATUS_SUCCESS);
}

//----------------------------------------------------------------------------------------
//Enable the TSI interface 
//----------------------------------------------------------------------------------------
BOOL TSI_MICCO_B0_DdsiTouchPanelEnable(void)
{
    //Sequence for enable TSI
    // 1. Set up TSI registers in Micco 
    //  2. Enable Interrupt from Micco Driver
    DWORD threadID;
    //UINT32 Irq;
	

    //RETAILMSG(1, (TEXT("[TOUCH] +TSI_MICCO_B0_DdsiTouchPanelEnable Touch panel Enable Start\r\n"))); 

    PHYSICAL_ADDRESS RegPA;
    if (g_pOSTRegs == NULL)
    {
         RegPA.QuadPart = MONAHANS_BASE_REG_PA_OST;
         g_pOSTRegs = (P_XLLP_OST_T) MmMapIoSpace(RegPA, sizeof(XLLP_OST_T), FALSE);
    }

    if ( g_hMiccoDrv==NULL)
    {
        //obtain micco driver handle
        g_hMiccoDrv=CreateFile(PIC_FILE_NAME, 0, 0, NULL, 0, 0, NULL);
        //map OST registers
        if (g_hMiccoDrv == INVALID_HANDLE_VALUE)
        {
            RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel Enable error - INVALID_HANDLE_VALUE Micco Drv\r\n")));
            return FALSE;
	  }
    }

    EnableTSI_LDO();

    ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2, 0x18, 0xff, NULL);
    ModifyMiccoReg(XLLP_MICCO_TSI_CONTROL_2, 0x80, 0xff, NULL);

    ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2, 0x18, 0xff, NULL);
    Sleep(40);
	
    ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2, 0x10, 0xff, NULL);

    //create the IST
    g_hTouchIST = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TouchISTThread,NULL,0,&threadID);
    if (!g_hTouchIST)
        RETAILMSG(1, (_T("[touch]: ERROR: Can't create touch thread\r\n")));
    else
        RETAILMSG(1, (_T("[Touch]: Created thread successfully\r\n")));
	
    g_hTouchIST_TerminateEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
    
    //enable Micco Intrrupt
    EnableTouchInterrupt();
    if(!SetMiccoTSIMode(TSI_PEN_DETECT))
    {
        RETAILMSG(1, (_T("ERROR: Touch panel Enable can't SetMiccoTSI Err\r\n")));
        return FALSE;
    }

#if 0

	RETAILMSG(DEBUG_TOUCH,(TEXT("-TSI_MICCO_B0_DdsiTouchPanelEnable \r\n")));
	Irq = IRQ_OSMR1;
	if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof Irq, &gIntrTouchChanged, sizeof gIntrTouchChanged, NULL))
	{
		RETAILMSG(1, (TEXT("ERROR: Failed to request the touch changed sysintr.\r\n")));
		gIntrTouchChanged = SYSINTR_UNDEFINED;
		return(FALSE);
	}
	else {
		RETAILMSG(1, (TEXT("OSMR1=%d, IRQ=%d, TouchChangedIRQ=%d\r\n"), XLLP_INTC_S_OST_M1, Irq,  gIntrTouchChanged));
		XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);
	}
#endif

    // Todo: Do we need dynamic map here?
    gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;
    XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);

    return(TRUE);
}





//----------------------------------------------------------------------------------------
//Note that TSI_MICCO_B0_DdsiTouchPanelDisable also called when attqahing 
//----------------------------------------------------------------------------------------
void	TSI_MICCO_B0_DdsiTouchPanelDisable(void)
{
    if ( g_hMiccoDrv==NULL)
        return; // TSI_MICCO_B0_DdsiTouchPanelEnable was not called yet, just return

    //Sequence for disable TSI
    // 1. disable Interrupt from Micco Driver
    // 2. Clear TSI registers in Micco 
	
    //RETAILMSG(1, (TEXT("[TOUCH] +TSI_MICCO_B0_DdsiTouchPanelDisable Touch panel Disable Start\r\n")));

	
    if ( g_hTouchIST_TerminateEvent!=NULL)
    {
        //disable Micco Intrrupt - PMIC_INT (GPIO18)
        DisableTouchInterrupt();
        //Kill the IST thread
        //signal the thread it should terminate 
        SetEvent(g_hTouchIST_TerminateEvent);
        WaitForSingleObject(g_hTouchIST,INFINITE);
        CloseHandle(g_hTouchIST);
        g_hTouchIST = NULL;
        //close and release event hadle 
        CloseHandle(g_hTouchIST_TerminateEvent);
        g_hTouchIST_TerminateEvent=NULL;
        if(!ClearMiccoTSI())
            RETAILMSG(1, (_T("ERROR:TouchPanelDisable can't DeallocateTouchPanelResources Err\r\n")));

        //unmap ost registers
        if (g_pOSTRegs != NULL)
        {
            MmUnmapIoSpace(g_pOSTRegs, sizeof(XLLP_OST_T));
        }
    }

    //close handle to Micco Driver
    CloseHandle(g_hMiccoDrv);
	
    //RETAILMSG(1, (TEXT("[TOUCH] -TSI_MICCO_B0_DdsiTouchPanelDisable Touch panel Disable End\r\n"))); 
    return;
}



//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------
static BOOL ClearMiccoTSI(void)
{
	
    BYTE reg[2];	//1st byte reg address 2nd byte reg val for IO micco regs
    BOOL ret_val;

    //RETAILMSG(1, (TEXT("[TOUCH] +ClearMiccoTSI Start\r\n"))); 

    //restore ADC_MAN_CONTROL
    //get Micco reg adress:ADC_MAN_CONTROL
    reg[0] = XLLP_MICCO_ADC_MAN_CONTROL;
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
    if(!ret_val){
        RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant get XLLP_MICCO_ADC_MAN_CONTROL\r\n")));
        return(FALSE);		
    }

    reg[1] &= (LDO_ADC_ENABLE_MASK_CLR & MUX_MASK_CLR);
    PrevAdcManControl_Val &= LDO_ADC_ENABLE_SET;		//case LDO was prev set 
    reg[1] |= PrevAdcManControl_Val;

    //write to Micco HW:ADC_MAN_CONTROL
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
    if(!ret_val){
        RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant set XLLP_MICCO_ADC_MAN_CONTROL\r\n")));
        return(FALSE);
    }

    //---------------------------------------
    //restore ADC_AUTO_CONTROL_2
    //get Micco reg ADC_AUTO_CONTROL_2
    reg[0] = XLLP_MICCO_ADC_AUTO_CONTROL_2;
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
    if(!ret_val){
        RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant get XLLP_MICCO_ADC_AUTO_CONTROL_2\r\n")));
        return(FALSE);
    }

    reg[1] &= (PEN_DETECT_MASK_CLR & AUTO_TSI_MASK_CLR);
    //reg[1] |= PrevAdcAutoControl_2_Val;
	
    //set data to ADC_AUTO_CONTROL_2
	
    //write to Micco HW ADC_AUTO_CONTROL_2
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
    if(!ret_val){
        RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant set XLLP_MICCO_ADC_AUTO_CONTROL_2\r\n")));
        return(FALSE);
    }

    //RETAILMSG(1, (TEXT("[TOUCH] -ClearMiccoTSI End\r\n")));
    return(TRUE);
}


/*
 * TODO: Add Touch Power Handler here - Littleton
 */
void	TSI_MICCO_B0_DdsiTouchPanelPowerHandler(BOOL PowerOff)
{
	
    RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel power handler Start\r\n")));
    RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel power handler End\r\n")));	
    return;
}


/*
 * TODO: Anything to add here? - Littleton
 */
LONG TSI_MICCO_B0_DdsiTouchPanelAttach()
{
    RETAILMSG(1,(_T("+ DdsiTouchPanelAttach\r\n")));
    RETAILMSG(1,(_T("- DdsiTouchPanelAttach\r\n")));
    return(0);
}

/*
 * TODO: Anything to add here - Littleton
 */

LONG TSI_MICCO_B0_DdsiTouchPanelDetach()
{
    RETAILMSG(1,(_T("+ DdsiTouchPanelDettach\r\n")));
    RETAILMSG(1,(_T("- DdsiTouchPanelDetach\r\n")));
	return(0);
}

//----------------------------------------------------------------------------------------
// Set up \ re-arm OSMR interrupt to be used 
//----------------------------------------------------------------------------------------

static void EnableTouchTimerInterrupt(UINT32 TimeInterval)
{
    volatile UINT32 TimerMatch;

    //RETAILMSG(1,(TEXT("[touch] + EnableTouchTimerInterrupt \r\n")));

    // XLLI initializes oier and rtsr to zeros, so no further
    // initialization needs to be done.  Match timers and
    // alarms are disabled.
    //
    // Current usage of Match registers:
    //  M0 - Scheduler
    //  M1 - Touch Panel
    //  M2 - Profiler

    // Configure and arm the timer interrupt  to interrupt every specified system tick interval.
    //RETAILMSG(DEBUG_TOUCH,(_T("[touch] + Enable Touch Timer Interrupt Start\r\n")));

    //shachar TimerMatch = (g_pOSTRegs->oscr0 + TimeInterval); 
    TimerMatch = g_pOSTRegs->oscr0;
	
    if((TimerMatch + TimeInterval)<TimerMatch)  
    {
        RETAILMSG(DEBUG_TOUCH,(_T("[touch] + Touch Timer Roll Back!!!\r\n")));
        TimerMatch = (TimeInterval - (((1<<32)-1)-TimerMatch));//timer roll
    }
    else	
        TimerMatch += TimeInterval; 

	
    //XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);
    XllpOstConfigureTimer(g_pOSTRegs, MatchReg1, TimerMatch);
    //if ( !XllpINTCIsSourceEnabled(XLLP_INTC_S_OST_M1))
    //{
    //    XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);
    //}

    //RETAILMSG(1,(TEXT("[touch] - EnableTouchTimerInterrupt \r\n")));
    return;
}


//----------------------------------------------------------------------------------------
// Enable \ Disable  the TSI_Ready Interrupt 
//----------------------------------------------------------------------------------------

static BOOL EnableTSI_X_Y_ReadyInterrupt(void)
{
    BOOL ret=TRUE;
    DWORD	event = PIC_EVENT_TSI_READY;
    if ( g_TSI_X_Y_ReadyEvent ==NULL)  //only needed in the first time,
        ret= DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_EVENT_HANDLE,&event,sizeof(DWORD), &g_PenDownEvent, sizeof(DWORD), NULL,NULL);
    //enable the event in MICCO MASK Register
    if ( !ret)
        ret= DeviceIoControl(g_hMiccoDrv,PIC_IO_ENABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
    return ret;
}

static BOOL DisableTSI_X_Y_ReadyInterrupt(void)
{
    DWORD event = PIC_EVENT_TSI_READY;
    return DeviceIoControl(g_hMiccoDrv,PIC_IO_DISABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
}

//----------------------------------------------------------------------------------------
// Enable  the pen detect interrupt 
//----------------------------------------------------------------------------------------

static BOOL EnableTouchInterrupt(void)
{
    BOOL ret=TRUE;
    DWORD	event = PIC_EVENT_ADC_PEN_DOWN;
    //RETAILMSG(1,(TEXT("[touch] + EnableTouchInterrupt\r\n")));
    //create event inside MICCO Driver, only needed once
    if ( g_PenDownEvent ==NULL)  //only needed in the first time,
        ret= DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_EVENT_HANDLE,&event,sizeof(DWORD), &g_PenDownEvent, sizeof(DWORD), NULL,NULL);
    //enable the event in MICCO MASK Register
    if ( ret)
        ret= DeviceIoControl(g_hMiccoDrv,PIC_IO_ENABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);

    //RETAILMSG(1,(TEXT("[touch] - EnableTouchInterrupt\r\n")));
    return ret;
}

//----------------------------------------------------------------------------------------
//  Disable the pen detect interrupt 
//----------------------------------------------------------------------------------------
static BOOL DisableTouchInterrupt(void)
{
    DWORD event = PIC_EVENT_ADC_PEN_DOWN;
    return DeviceIoControl(g_hMiccoDrv,PIC_IO_DISABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
}


//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------


void TSI_MICCO_B0_DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags, INT *pUncalX, INT *pUncalY)

{
    static BOOL TouchIrq = TRUE;
    BOOL bIDone=TRUE;

    //RETAILMSG(1,(TEXT("[touch] + TSI_MICCO_B0_DdsiTouchPanelGetPoint Start \r\n")));
	
    if (!pTipStateFlags || !pUncalX || !pUncalY)
    {
        DEBUGMSG(DEBUG_TOUCH, (TEXT("ERROR: TSI_MICCO_B0_DdsiTouchPanelGetPoint: Invalid parameter(s).\r\n")));
        return;
    }

    //RETAILMSG(1, (TEXT("DdsiTouchPanelGetPoint: XLLP_INTC_ICPR= 0x%x\r\n"),XllpReadINTCReg(XLLP_INTC_ICPR)));
  	
    //we need to find what caused us get here , could be pen up \ down or timer interrupt
    //let's start with timer 
    //we are in this routine because we are handling interrupt
    //if OSMR2 interrupt is disaled - this is what caused us to get here
	
    // FIXME: Yu Tang: Hacked to pass compiling
    //XLLP_BOOL_T bIsTimerIntrEna = XllpINTCIsSourceEnabled(XLLP_INTC_S_OST_M1);
    XLLP_BOOL_T bIsTimerIntrEna = XLLP_FALSE; // XllpINTCIsSourceEnabled(XLLP_INTC_S_OST_M1);
    if ( !bIsTimerIntrEna && penStatus==PEN_STATUS_DOWN)
    {
        bIDone=FALSE;
    }
    /*else if ( penStatus==PEN_STATUS_INIT)
        InterruptDone(SYSINTR_TOUCH_CHANGED);*/

    *pTipStateFlags = PDDSampleTouchScreen(pUncalX, pUncalY);

    // if previous valid sample had TouchSampleDownFlag ( Pen Down ) and
    //now pen is up - we should report only TouchSampleValidFlag
    // the pen isn't currently down, send the MDD a pen-up "event".
    if ( penStatus==PEN_STATUS_INIT)
    {
        *pTipStateFlags = TouchSampleIgnore;
    }
	
    if ( *pTipStateFlags&TouchSampleDownFlag)
        EnableTouchTimerInterrupt(TOUCH_TIMER_INCREMENT_TSI_OSMR1);

    if ( !bIDone)
        InterruptDone(gIntrTouchChanged);

    //RETAILMSG(DEBUG_TOUCH,(_T("[touch] - TSI_MICCO_B0_DdsiTouchPanelGetPoint  End\r\n")));
}


BOOL	TSI_MICCO_B0_DdsiTouchPanelGetDeviceCaps(INT iIndex,LPVOID  lpOutput){

    //RETAILMSG(DEBUG_TOUCH,(TEXT("+ TSI_MICCO_B0_DdsiTouchPanelGetDeviceCaps Touch panel Get DeviceCaps Start\r\n")));
    if (lpOutput == NULL)
    {
        ERRORMSG(1,(__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
        SetLastError(ERROR_INVALID_PARAMETER);
        RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps false 1\r\n")));
        return (FALSE);
    }

    switch (iIndex)
    {
    case TPDC_SAMPLE_RATE_ID:
        {
            TPDC_SAMPLE_RATE  *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;

            pTSR->SamplesPerSecondLow = TOUCHPANEL_SAMPLE_RATE_LOW;
            pTSR->SamplesPerSecondHigh = TOUCHPANEL_SAMPLE_RATE_HIGH;
            pTSR->CurrentSampleRateSetting = TOUCHPANEL_SAMPLE_RATE_HIGH;
        }
        break;

    case TPDC_CALIBRATION_POINT_COUNT_ID:
        {
            TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
            pTCPC->flags = 0;
            pTCPC->cCalibrationPoints = 5;
        }
        break;

    case TPDC_CALIBRATION_POINT_ID:
        RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps TPDC_CALIBRATION_POINT_ID\r\n")));
		return(TouchDriverCalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));

    default:
        ERRORMSG(1,(__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
        SetLastError(ERROR_INVALID_PARAMETER);
        RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps false 2\r\n")));
        return (FALSE);
    }
    //RETAILMSG(DEBUG_TOUCH,(TEXT("- TSI_MICCO_B0_DdsiTouchPanelGetDeviceCaps Touch panel Get DeviceCaps End\r\n")));
    return (TRUE);
}


BOOL TSI_MICCO_B0_DdsiTouchPanelSetMode(INT iIndex,LPVOID  lpInput){

    BOOL  ReturnCode = FALSE;

    //RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel Set mode Start\r\n")));
    switch (iIndex)
    {
    case TPSM_SAMPLERATE_LOW_ID:
    case TPSM_SAMPLERATE_HIGH_ID:
        SetLastError(ERROR_SUCCESS);
        ReturnCode = TRUE;
        break;

    default:
        SetLastError(ERROR_INVALID_PARAMETER);
        break;
    }
    //RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Set mode End\r\n")));
    return(ReturnCode);
}


//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------
INT evaluateSample(INT x0, INT x1, int maxError)
{

    INT retval = TouchSampleValidFlag ;
    INT diff;
    
    //RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel evaluate Sample Start\r\n")));
	
    if (x1==0)
        retval = TouchSampleValidFlag;
    else
    {
        diff=x0-x1;
        diff= diff>0 ? diff: -diff;
        if (diff>maxError)
            retval=TouchSampleIgnore;
    }
    //RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel evaluate Sample End\r\n")));
    return(retval);
}

//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------
static TOUCH_PANEL_SAMPLE_FLAGS PDDSampleTouchScreen(INT *x,INT *y)
{
    TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
    int TmpX = 0;
    int TmpY = 0;  
    DWORD res;
    
    //RETAILMSG(1,(TEXT("+Touch panel PDD Sample Touch Screen - Start\r\n")));

    //TSI is in PEN_DETECTION mode & also Time Int in case pen_down state is enable 
    //, in order to get x,y reading we need to :

    // 0.disable touch int 
    // 1. switch to AUTO TSI ( while disabling and mask out PEN_DETECT
    // 2.wait for TSI Ready EVENT, meaning we have valid reading from ADC  
    // 3. read X,Y coordinates and validate 
    // 4. switch back to PEN_DETECTION, un-mask PEN_DETECT Inter.
    // 5.wait for pen_detect event, since pen event might occur during measurment
    if( penStatus==PEN_STATUS_INIT)
    {
        EnableTouchInterrupt();
        TmpStateFlags = TouchSampleIgnore;
        return TmpStateFlags;
    }
    if( penStatus==PEN_STATUS_UP)
    {
        g_PreX=TmpX;
        g_PreY=TmpY;
        TmpStateFlags = TouchSampleIgnore;
        return TmpStateFlags;

    }
	

    
    // 1.1- Disable pen detect interrupt
    //DisableTouchInterrupt(); //
    // 1.2 - reset the event for TSI ready, cleat any previous signaling
    ResetEvent(g_TSI_X_Y_ReadyEvent);
    // 1.3 Set TSI Mode and enabler interrupt
    SetMiccoTSIMode(TSI_AUTO);
    EnableTSI_X_Y_ReadyInterrupt();
    // 1.4 wait for AUTO_TSI ready event
    res = WaitForSingleObject(g_TSI_X_Y_ReadyEvent,10/*AUTO_TSI_SAMPLE_RATE*2*/);
    // 1.5 
    if ( res==WAIT_TIMEOUT)
    {
        //we could not get a valid reading - return ignore
        RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR, TSI_READY TIMEOUT\r\n")));
        TmpStateFlags |= TouchSampleIgnore;
        return TmpStateFlags;
    }

    //if here we can safely read X,Y
    // 1.6 
    if (TsiRead_X_Y(&TmpX,&TmpY)!=TOUCH_STATUS_SUCCESS)
    {
        RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR, Could not read X,Y from MICCO\r\n")));
        TmpStateFlags |= TouchSampleIgnore;
        return TmpStateFlags;
    }

    // 1.6 - evaluate the sample
    if ( penStatus==PEN_STATUS_DOWN)
    {
        TmpStateFlags = TouchSampleDownFlag;
        if (evaluateSample(TmpX, g_PreX,DELTA_TSI_X_COORD_VARIANCE) == TouchSampleIgnore)
        {
            TmpStateFlags |= TouchSampleIgnore;
            RETAILMSG(DEBUG_TOUCH,(TEXT("Invalid X sample\r\n")));
        }
        else  if (evaluateSample(TmpY, g_PreY,DELTA_TSI_Y_COORD_VARIANCE)==TouchSampleIgnore)
        {
            TmpStateFlags |= TouchSampleIgnore;
            RETAILMSG(DEBUG_TOUCH,(TEXT("Invalid Y sample\r\n")));
        }
        else
            TmpStateFlags |= TouchSampleValidFlag;
    }
    //////////////////////////////////////////////////////////////////////////
    *x=TmpX;
    *y=TmpY;
    if (TmpStateFlags&TouchSampleValidFlag)
    {
         g_PreX=TmpX;
         g_PreY=TmpY;
    }

    DisableTSI_X_Y_ReadyInterrupt();
    //enable the PEN_DETECT interrupt, we should get interrupt now 
    //EnableTouchInterrupt();
    //now we can switch back to PEN_DETECT Mode
    SetMiccoTSIMode(TSI_PEN_DETECT);
    //let's wait couple of milli and read back pen status
    XllpOstDelayMilliSeconds(g_pOSTRegs,5);
    penStatus = GetPenStatus();

    if( penStatus==PEN_STATUS_UP)
    {
        EnableTouchInterrupt();
        TmpStateFlags=TouchSampleValidFlag;
    }

    DEBUGMSG(DEBUG_TOUCH,(TEXT("[TOUCH] x=%d, y=%d,tateFlags = %d\r\n"),*x,*y,TmpStateFlags));
    return(TmpStateFlags);
}



TOUCH_STATUS_T	TsiRead_X_Y(int *X, int *Y)
{
	
    BYTE reg[2];
	
	Sleep(20);
	
    //read TSI_X_MSB
    reg[0] = XLLP_MICCO_TSI_X_MSB;
    if ( !DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
        return TOUCH_STATUS_FAILURE;
				
    *X = (reg[1]);
    *X = (*X<<2);

    //read TSI_Y_MSB
    reg[0] = XLLP_MICCO_TSI_Y_MSB;
    if (!DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
        return TOUCH_STATUS_FAILURE;
				
    *Y = (reg[1]);
    *Y = (*Y<<2);

    //*Y = reg[1];//-0x12;
	

    //read TSI_X_PLUS_Y_LSB
    reg[0] = XLLP_MICCO_TSI_XY_MSB;
    if ( !DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
        return TOUCH_STATUS_FAILURE;
		
    *X = (*X|(reg[1]&TSI_X_MASK));
    *Y = (*Y|(reg[1]&TSI_Y_MASK)>>2);
    

    TSP_TransXY(X,Y);

    return TOUCH_STATUS_SUCCESS;
}

//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------

DWORD TouchISTThread(void* pParam)
{
    DWORD	dwTimeout = INFINITE;
    DWORD	waitStatus;

    HANDLE waitHandle[2]={g_PenDownEvent,g_hTouchIST_TerminateEvent}; // 0  - Micco Event, 1 - Terminate Thread

    BOOL bLoop = TRUE;
	
    DWORD oldMode=0;
    BOOL bPenStatusTransition;
    PEN_STATUS previousPenStatus;

    //RETAILMSG(1, (TEXT("[TOUCH] +TouchISTThread Started\r\n"))); 
    while(bLoop)
    {
		
        waitStatus = WaitForMultipleObjects(2,waitHandle,FALSE,dwTimeout);
        switch(waitStatus){		
        case WAIT_TIMEOUT:
            //RETAILMSG(1, (TEXT("[TOUCH] TouchISTThread  Timeout\n"))); 
            return(0);
        case WAIT_OBJECT_0: //g_PenDownEvent[0] event occured.
            //RETAILMSG(1, (TEXT("[TOUCH] TouchISTThread  g_PenDownEvent[0] event occured\n"))); 
            //get Micco reg adress:ADC_MAN_CONTROL		
            //update global pen status 
            previousPenStatus = penStatus; 
            penStatus = GetPenStatus();
		
            //we only care about transition ( up - > Down, down - > up , init -> up \ down
            bPenStatusTransition= previousPenStatus!=penStatus;
            if ( bPenStatusTransition)
            {
                if ( penStatus==PEN_STATUS_UP)
                {
                    DEBUGMSG(DEBUG_TOUCH,(TEXT("[TOUCH] Pen UP\r\n")));
                }
                if ( penStatus==PEN_STATUS_DOWN)
                {
                    DEBUGMSG(DEBUG_TOUCH,(TEXT("[TOUCH] Pen Down\r\n")));
                }
            }
				

            //we also want to ignore the event duing boot, we also report pen down only to MSFT
            if ( !bPenStatusTransition || previousPenStatus==PEN_STATUS_INIT || penStatus==PEN_STATUS_UP )
                break; //don't care , no transisiotn
            g_PreX=0;
            g_PreY=0;
            DisableTouchInterrupt();

            SetEvent(hTouchPanelEvent);
            break;
        case (WAIT_OBJECT_0+1):
            bLoop = FALSE;
            break;
        default:
            break;		
        }//switch 
    }//while

    //interrupt here can be only received from MICCO ( GPIO Interrupt ) 
	
    //RETAILMSG(1, (TEXT("[TOUCH] -TouchISTThread Terminated\n"))); 
    return(1);
}


TOUCH_STATUS_T ReadMiccoReg(BYTE reg_address, BYTE *value)
{
    BOOL ret_val;
    BYTE reg[2];	

    if (!value) return TOUCH_STATUS_FAILURE;
	
    reg[0] = reg_address;

    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg, sizeof(BYTE), reg+1, sizeof(BYTE), NULL, NULL);

    if (!ret_val) return TOUCH_STATUS_FAILURE;

    *value = reg[1];
	
    //RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ReadMiccoReg[%2x]=%02x\r\n"), reg_address, *value));
    return TOUCH_STATUS_SUCCESS;
}

TOUCH_STATUS_T ModifyMiccoReg(BYTE reg_address,BYTE set_mask,BYTE clear_mask,LPBYTE prevValue)
{
    BYTE reg[2];	
    reg[0] = reg_address;
    BOOL ret_val;
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
    if(!ret_val)
    {
        return TOUCH_STATUS_FAILURE;
    }
    //update original value
    if (prevValue!=NULL )
        *prevValue = reg[1];

    //set the masks
    reg[1]&= clear_mask;
    reg[1]|= set_mask;

    //write value to reg
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
    if(!ret_val)
        return TOUCH_STATUS_FAILURE;

    return TOUCH_STATUS_SUCCESS;
}



PEN_STATUS GetPenStatus()
{
    BOOL bPenDown,ret_val;
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_PEN_DOWN, NULL,0, &bPenDown, sizeof(BOOL), NULL,NULL);
    if(!ret_val)
    {
        RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR - Cant get XLLP_TOUCH_STATUS_A\r\n")));
        return PEN_STATUS_INIT;
    }
    return bPenDown?PEN_STATUS_DOWN:PEN_STATUS_UP;
}


void TSP_TransXY(INT *px, INT *py)
{
	
    *px = (*px - TSP_MINX) * TSP_LCDX / (TSP_MAXX - TSP_MINX);

    *py = (*py - TSP_MINY) * TSP_LCDY / (TSP_MAXY - TSP_MINY);

    if (*px  <        0) *px = 0;
    if (*px >= TSP_LCDX) *px = TSP_LCDX - 1;

    if (*py  <        0) *py = 0;
    if (*py >= TSP_LCDY) *py = TSP_LCDY - 1;

	RETAILMSG(1, (L"x cordinate(%d), y cordinate(%d))\r\n",*px,*py));

}

